using System.Linq;
using NUnit.Framework;
using Orchard.Azure.Services.Environment.Configuration;
using Orchard.Environment.Configuration;
using Orchard.FileSystems.Media;

namespace Orchard.Azure.Tests.Environment.Configuration
{
    [TestFixture]
    public class AzureShellSettingsManagerTests : AzureVirtualEnvironmentTest
    {
        private IShellSettingsManager _shellSettingsManager;

        protected override string StorageConnectionStringName { get; } = Constants.ShellSettingsStorageConnectionStringSettingName;

        protected override void OnInit()
        {
            _shellSettingsManager = new AzureBlobShellSettingsManager(
                new Moq.Mock<IMimeTypeProvider>().Object,
                new Moq.Mock<IShellSettingsManagerEventHandler>().Object);
        }

        [SetUp]
        public void Setup()
        {
            // ensure default container is empty before running any test
            DeleteAllBlobs(Constants.ShellSettingsDefaultContainerName, DevAccount);
        }

        [TearDown]
        public void TearDown()
        {
            // ensure default container is empty after running tests
            DeleteAllBlobs(Constants.ShellSettingsDefaultContainerName, DevAccount);
        }

        [Test]
        public void SingleSettingsFileShouldComeBackAsExpected()
        {

            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });

            var settings = _shellSettingsManager.LoadSettings().Single();
            Assert.That(settings, Is.Not.Null);
            Assert.That(settings.Name, Is.EqualTo("Default"));
            Assert.That(settings.DataProvider, Is.EqualTo("SQLCe"));
            Assert.That(settings.DataConnectionString, Is.EqualTo("something else"));
        }

        [Test]
        public void SettingsShouldBeOverwritable()
        {
            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe2", DataConnectionString = "something else2" });

            var settings = _shellSettingsManager.LoadSettings().Single();
            Assert.That(settings, Is.Not.Null);
            Assert.That(settings.Name, Is.EqualTo("Default"));
            Assert.That(settings.DataProvider, Is.EqualTo("SQLCe2"));
            Assert.That(settings.DataConnectionString, Is.EqualTo("something else2"));
        }

        [Test]
        public void MultipleFilesCanBeDetected()
        {

            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Another", DataProvider = "SQLCe2", DataConnectionString = "something else2" });

            var settings = _shellSettingsManager.LoadSettings();
            Assert.That(settings.Count(), Is.EqualTo(2));

            var def = settings.Single(x => x.Name == "Default");
            Assert.That(def.Name, Is.EqualTo("Default"));
            Assert.That(def.DataProvider, Is.EqualTo("SQLCe"));
            Assert.That(def.DataConnectionString, Is.EqualTo("something else"));

            var alt = settings.Single(x => x.Name == "Another");
            Assert.That(alt.Name, Is.EqualTo("Another"));
            Assert.That(alt.DataProvider, Is.EqualTo("SQLCe2"));
            Assert.That(alt.DataConnectionString, Is.EqualTo("something else2"));
        }

        [Test]
        public void NewSettingsCanBeStored()
        {
            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });

            var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux" };

            Assert.That(_shellSettingsManager.LoadSettings().Count(), Is.EqualTo(1));
            _shellSettingsManager.SaveSettings(foo);
            Assert.That(_shellSettingsManager.LoadSettings().Count(), Is.EqualTo(2));

            foo = _shellSettingsManager.LoadSettings().Where(s => s.Name == "Foo").Single();
            Assert.That(foo.Name, Does.Contain("Foo"));
            Assert.That(foo.DataProvider, Does.Contain("Bar"));
            Assert.That(foo.DataConnectionString, Does.Contain("Quux"));
        }

        [Test]
        public void SettingsCanContainSeparatorChar()
        {
            _shellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;" });

            var settings = _shellSettingsManager.LoadSettings().Where(s => s.Name == "Default").Single();
            Assert.That(settings.DataConnectionString, Is.EqualTo("Server=tcp:tjyptm5sfc.database.windows.net;Database=orchard;User ID=foo@bar;Password=foo;Trusted_Connection=False;Encrypt=True;"));
        }
    }
}
